package utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class GPSConverterUtils {
    public static final String BAIDU_LBS_TYPE = "bd09ll";
    public static double pi = 3.1415926535897932384626;
    public static double a = 6378245.0;
    public static double ee = 0.00669342162296594323;

    /**
     * 84 to 火星坐标系 (GCJ-02)
     *
     * @param lat
     * @param lon
     */
    public static GPS gps84_To_Gcj02(double lon, double lat) {
        if (outOfChina(lon, lat)) {
            return null;
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new GPS(mgLon, mgLat);
    }

    /**
     * * 火星坐标系 (GCJ-02) to 84
     * * @param lon * @param lat * @return
     */
    public static GPS gcj_To_Gps84(double lon, double lat) {
        GPS gps = transform(lon, lat);
        double lontitude = lon * 2 - gps.getLon();
        double latitude = lat * 2 - gps.getLat();
        return new GPS(lontitude, latitude);
    }

    /**
     * 将 GCJ-02 坐标转换成 BD-09 坐标
     *
     * @param gg_lat
     * @param gg_lon
     */
    public static GPS gcj02_To_Bd09(double gg_lon, double gg_lat) {
        double x = gg_lon, y = gg_lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
        double bd_lon = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new GPS(bd_lon, bd_lat);
    }
    /**
     * * 将 BD-09 坐标转换成GCJ-02 坐标 *
     * * @param
     * bd_lat * @param bd_lon * @return
     */
    public static GPS bd09_To_Gcj02(double bd_lon, double bd_lat) {
        double x = bd_lon - 0.0065;
        double y = bd_lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new GPS(gg_lon, gg_lat);
    }

    /**
     * (BD-09)-->84
     *
     * @param bd_lat
     * @param bd_lon
     * @return
     */
    public static GPS bd09_To_Gps84(double bd_lon, double bd_lat) {
        GPS gcj02 = bd09_To_Gcj02(bd_lon, bd_lat);
        GPS map84 = gcj_To_Gps84(gcj02.getLon(), gcj02.getLat());
        return map84;
    }
    /**
     * is or not outOfChina
     *
     * @param lat
     * @param lon
     * @return
     */
    public static boolean outOfChina(double lon, double lat) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    }

    public static GPS transform(double lon, double lat) {
        if (outOfChina(lon, lat)) {
            return new GPS(lon, lat);
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new GPS(mgLon, mgLat);
    }

    public static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
                + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }
    public static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
                * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
                * pi)) * 2.0 / 3.0;
        return ret;
    }

    public static void main(String[] args) {
        //经纬度
        String s = "[[114.056291,22.54841], [114.056334,22.539869], [114.056334,22.539869]]";
        String s2 = "[[[114.04849571048821,22.525775216223984], [114.04716731124387,22.5292466601697]], [[114.04849571048821,22.525775216223984], [114.04849571048821,22.525775216223984]]]";
        JSONArray sArray = JSONObject.parseArray(s);
        for (int i = 0; i < sArray.size(); i++) {
            JSONArray pointArray = sArray.getJSONArray(i);
//            System.out.println(pointArray.getDouble(0) + "," + pointArray.getDouble(1));
            GPS gps = gcj_To_Gps84(pointArray.getDouble(0), pointArray.getDouble(1));
            s = s.replaceAll(pointArray.getDouble(0) + "", gps.getLon() + "");
            s = s.replaceAll(pointArray.getDouble(1) + "", gps.getLat() + "");
        }
        System.out.println(s);
        JSONArray s2Array = JSONObject.parseArray(s2);
        for (int i = 0; i < s2Array.size(); i++) {
            JSONArray array = s2Array.getJSONArray(i);
            for (int j = 0; j < array.size(); j++) {
                JSONArray pointArray = array.getJSONArray(j);
                GPS gps = gcj_To_Gps84(pointArray.getDouble(0), pointArray.getDouble(1));
                s2 = s2.replaceAll(pointArray.getDouble(0) + "", gps.getLon() + "");
                s2 = s2.replaceAll(pointArray.getDouble(1) + "", gps.getLat() + "");
            }
        }
        System.out.println(s2);
    }

    public static void main2(String[] args) {
        String s = "[[114.049476,22.534619],[114.056375,22.534649],[114.056332,22.539782],[114.056375,22.534649],[114.056412,22.530744],[114.056375,22.534649],[114.056262,22.539891],[114.056682,22.528767],[114.056661,22.522939],[114.056071,22.515467],[114.056661,22.522939],[114.053603,22.523049],[114.049558,22.522979],[114.053603,22.523049],[114.052273,22.526518],[114.053603,22.523049],[114.053603,22.523049],[114.056682,22.528767],[114.056629,22.523069],[114.056242,22.51838],[114.056629,22.523069],[114.056661,22.522939],[114.056629,22.523069],[114.061478,22.523147],[114.056629,22.523069],[114.058731,22.524738],[114.056629,22.523069],[114.058667,22.52117],[114.046973,22.518316],[114.050942,22.516294],[114.053839,22.51562],[114.056049,22.515382],[114.058173,22.515442],[114.060319,22.515799],[114.063538,22.516849],[114.066177,22.518415],[114.060319,22.515799],[114.060748,22.514173],[114.050942,22.516294],[114.052294,22.519228],[114.050942,22.516294],[114.049784,22.513797],[114.056092,22.515363],[114.061693,22.516274],[114.066113,22.518435],[114.068216,22.52117],[114.068344,22.523113],[114.068087,22.5289],[114.068344,22.523113],[114.07005,22.528173],[114.068344,22.523113],[114.066081,22.527935],[114.061693,22.516274],[114.069283,22.523089],[114.049408,22.544399],[114.05621,22.544538],[114.062969,22.544682],[114.049408,22.544399],[114.062969,22.544682],[114.063044,22.54271],[114.05621,22.544538],[114.056248,22.546614],[114.104749,22.535682],[114.10477,22.538437],[114.104685,22.540775],[114.10477,22.538437],[114.103419,22.537763],[114.104492,22.549119],[114.104406,22.555975],[114.104492,22.562277],[114.104191,22.566953],[114.104492,22.562277],[114.097496,22.56192],[114.104406,22.555975],[114.092947,22.5555],[114.072696,22.565585],[114.07291,22.55536],[114.073082,22.542459],[114.072696,22.565585],[114.068748,22.561305],[114.072696,22.565585],[114.075657,22.561741],[114.07291,22.55536],[114.068018,22.546205],[114.07291,22.55536],[114.076558,22.547592],[114.063059,22.54458],[114.06308,22.542638],[114.063123,22.5402],[114.06308,22.542638],[114.060977,22.542677],[114.06308,22.542638],[114.065505,22.542756],[114.063187,22.539713],[114.063294,22.528842],[114.063927,22.526503],[114.064839,22.523084],[114.066212,22.518407],[114.063187,22.539713],[114.060226,22.535591],[114.063187,22.539713],[114.060226,22.535591],[114.063294,22.528842],[114.062071,22.521875],[114.063294,22.528842],[114.067264,22.525919],[114.062915,22.548643],[114.063065,22.544635],[114.062915,22.548643],[114.063065,22.544635],[114.060876,22.544754],[114.063065,22.544635],[114.065431,22.544739],[114.067619,22.555678],[114.063028,22.559681],[114.056118,22.55976],[114.048908,22.553895],[114.043201,22.553459],[114.067619,22.555678],[114.043201,22.553459],[114.040197,22.557026],[114.043201,22.553459],[114.045046,22.550645],[114.048908,22.553895],[114.046119,22.559285],[114.056118,22.55976],[114.058393,22.555441],[114.063028,22.559681],[114.063028,22.559681],[113.996495,22.540741],[114.002461,22.543278],[114.008812,22.544031],[114.011645,22.546765],[114.015378,22.552195],[114.029712,22.55279],[114.034561,22.553583],[114.104685,22.544704],[114.104738,22.540825],[114.104738,22.540825],[114.104738,22.540825],[114.104685,22.544704],[114.104738,22.540825],[114.102346,22.542609],[114.104685,22.544704],[114.104738,22.540825],[114.104738,22.540825],[114.104738,22.540825],[114.104685,22.544704],[114.104738,22.540825],[114.10182,22.538655],[114.049413,22.539655],[114.068017,22.540032],[114.077045,22.540095],[114.086765,22.540463],[114.049413,22.539655],[114.056569,22.534601],[114.068017,22.540032],[114.086765,22.540463],[114.077045,22.540095],[114.079878,22.537439],[114.06799,22.539976],[114.073988,22.540273],[114.06799,22.539976],[114.073988,22.540273],[114.076209,22.542503]]";
        JSONArray sArray = JSONObject.parseArray(s);
        for (int i = 0; i < sArray.size(); i++) {
            JSONArray pointArray = sArray.getJSONArray(i);
//            System.out.println(pointArray.getDouble(0) + "," + pointArray.getDouble(1));
            GPS gps = gcj_To_Gps84(pointArray.getDouble(0), pointArray.getDouble(1));
            s = s.replaceAll(pointArray.getDouble(0) + "", gps.getLon() + "");
            s = s.replaceAll(pointArray.getDouble(1) + "", gps.getLat() + "");
        }
        System.out.println(s);
    }
}

